/**
 * Convert a canvas to a Blob using a streaming approach
 * @param canvas Canvas element
 * @param mimeType MIME type of the output image
 * @param quality Image quality (0-1, only for JPEG)
 * @param onProgress Optional callback for progress updates
 * @returns Promise with Blob
 */
export async function canvasToBlob(
  canvas: HTMLCanvasElement,
  mimeType: string = 'image/png',
  quality: number = 0.9,
  onProgress?: (progress: number) => void
): Promise<Blob> {
  return new Promise<Blob>((resolve, reject) => {
    try {
      // For very large canvases, we need to use a streaming approach
      // to avoid memory issues
      
      // Start progress at 0%
      if (onProgress) {
        onProgress(0);
      }
      
      // Use the canvas.toBlob method which is more memory efficient
      canvas.toBlob(
        (blob) => {
          if (blob) {
            // Complete progress
            if (onProgress) {
              onProgress(100);
            }
            resolve(blob);
          } else {
            reject(new Error('Failed to convert canvas to blob'));
          }
        },
        mimeType,
        quality
      );
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * Stream a Blob to a file download
 * @param blob Blob to download
 * @param filename Filename
 * @param onProgress Optional callback for progress updates
 */
export async function streamBlobToFile(
  blob: Blob,
  filename: string,
  onProgress?: (progress: number) => void
): Promise<void> {
  try {
    // Start progress at 0%
    if (onProgress) {
      onProgress(0);
    }
    
    // For very large blobs, we can use the Streams API
    // but for simplicity and compatibility, we'll use the traditional approach
    
    // Create a URL for the blob
    const url = URL.createObjectURL(blob);
    
    // Update progress to 50%
    if (onProgress) {
      onProgress(50);
    }
    
    // Create a link element
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    
    // Append the link to the document
    document.body.appendChild(link);
    
    // Click the link to trigger the download
    link.click();
    
    // Remove the link from the document
    document.body.removeChild(link);
    
    // Release the URL
    URL.revokeObjectURL(url);
    
    // Complete progress
    if (onProgress) {
      onProgress(100);
    }
  } catch (error) {
    throw error;
  }
}